package com.kly.order.serviceImpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.kly.dto.MemberDto;
import com.kly.dto.ProductCategoryDto;
import com.kly.dto.ProductDescriptionDto;
import com.kly.dto.ProductDto;
import com.kly.enums.*;
import com.kly.order.ServiceUtils;
import com.kly.order.db.dao.MemberDao;
import com.kly.order.db.dao.ProductCategoryDao;
import com.kly.order.db.dao.ProductDao;
import com.kly.order.db.entity.MemberEntity;
import com.kly.order.db.entity.ProductCategoryEntity;
import com.kly.order.db.entity.ProductEntity;
import com.kly.order.mapper.MemberMapper;
import com.kly.order.mapper.ProductCategoryMapper;
import com.kly.service.MemberService;
import com.kly.user.dto.PushMsgEvent;
import com.kly.user.enums.AppEnum;
import com.kly.user.enums.PushBizCodeEnum;
import com.kly.user.service.PushMsgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service("memberService")
public class MemberServiceImpl implements MemberService {

    @Resource
    MemberDao memberDao;

    @Resource
    MemberMapper mapper;

    @Resource
    ProductDao productDao;

    @Resource
    ProductCategoryDao productCategoryDao;

    @Resource
    ProductCategoryMapper productCategoryMapper;

    @Resource
    ProductDescriptionAndSubscriptionService PDSService;
    @Resource
    PushMsgService pushMsgService;

    /**
     * 获取会员信息
     *
     * @param userCode 用户码
     * @return 会员信息，不存在返回error
     */
    @Override
    public Response<MemberDto> getMemberInfo(String userCode, String appCode) {

        MemberEntity memberEntity = memberDao.getMembers(userCode, new Date());
        if (memberEntity != null) {
            MemberDto memberDto = mapper.toDto(memberEntity);

            //查询产品类别消息
            ProductCategoryEntity productCategory = productCategoryDao.getProductCategory(appCode, ProductCategory.MEMBER.getCode());
            if (productCategory != null) {
                ProductCategoryDto dto = productCategoryMapper.toDto(productCategory);
                memberDto.setMemberDescription(dto.getSubscriptions().get(0));
            }
            return Response.ok(memberDto);
        }
        return Response.error(TradeResultStatus.NO_MEMBER);
    }

    /**
     * 查询会员订阅
     *
     * @param userCode 用户码
     */
    @Override
    public Response<MemberDto> queryMemberSubscription(String appCode, String userCode, Integer productCategoryCode) {
        Map<String, Object> params = ServiceUtils.getParams();
        params.put("userCode", userCode);
        params.put("date", new Date());
        //查询会员信息
        List<MemberEntity> memberEntities = memberDao.selectByUser(params);
        params = ServiceUtils.getParams();
        params.put("productCategory", productCategoryCode);
        params.put("appCode", appCode);
        //查询产品类别消息
        List<ProductCategoryEntity> categoryList = productCategoryDao.selectByParams(params);
        ProductCategoryDto productCategoryDto = productCategoryMapper.toDto(categoryList.get(0));
        //查询产品信息
        List<ProductEntity> productEntities =
                productDao.selectByProductCategory(appCode, productCategoryCode);
        //获取会员产品描述
        List<ProductDescriptionDto> ProductDescriptions = new ArrayList<>();
        productEntities.forEach(product -> {
            String description = product.getDescription();
            String productCode = product.getProductCode();
            if (description != null && productCode != null) {
                ProductDescriptionDto productDescription = JSONUtil.toBean(description, ProductDescriptionDto.class);
                productDescription.setProductCode(productCode);
                productDescription.setSortBy(product.getSortBy());
                if (CollUtil.isNotEmpty(memberEntities)) {
                    if (memberEntities.get(0).getAutoRenew()==TradeType.TURN_ON_AUTO_RENEW.getType()){
                        productDescription.setCheck(getCheckStatues(memberEntities.get(0).getProductCode(), product.getSortBy()));
                    }
                }
                ProductDescriptions.add(productDescription);
            }
        });
        //当不存在会员信息时，则添加会员产品描述
        ProductCategoryDto.Subscriptions memberDescription = productCategoryDto.getSubscriptions().get(0);
        MemberDto memberDto;
        if (CollUtil.isEmpty(memberEntities)) {
            memberDto = new MemberDto();
            memberDto.setProductDescriptions(ProductDescriptions);
            memberDescription.setHeader(null);
        } else {
            final MemberEntity memberEntity = memberEntities.get(0);
            memberDto = mapper.toDto(memberEntity);
            memberDto.setProductDescriptions(ProductDescriptions);
            memberDescription.setHeader(getProductHeader(memberEntity));

        }
        //获取会员产品相关服务描述并添加返回值
        List<ProductCategoryDto.Subscriptions> subscriptions =
                PDSService.getSubscriptions(params, null, CollectionUtils.isNotEmpty(memberEntities));
        memberDto.setSubscriptions(subscriptions);
        //设置会员分类描述
        memberDto.setMemberDescription(memberDescription);
        return Response.ok(memberDto);
    }

    private String getProductHeader(MemberEntity memberEntity) {
        ProductEntity product = productDao.selectByProductCode(memberEntity.getProductCode());
        if (product != null) {
            //1、周会员、2月会员、3季度会员
            if (product.getSortBy() == 2) {
                return "Monthly subscribed";
            } else if (product.getSortBy() == 1) {
                return "Weekly subscribed";
            } else if (product.getSortBy() == 3) {
                return "3 Monthly subscribed";
            }
        }
        return "";
    }

    /**
     * 选择状态
     * @param productCode
     * @param sortBy
     * @return
     */
    private boolean getCheckStatues(String productCode, Integer sortBy) {
        boolean check = false;
        ProductEntity product = productDao.selectByProductCode(productCode);
        if (product != null) {
            //1、周会员、2月会员、3季度会员
            if (Objects.equals(product.getSortBy(), sortBy)) {
                check = true;
            }
        }
        return check;
    }

    /**
     * 关闭自动订阅
     *
     * @param userCode
     * @return
     */
    @Override
    public Response<MemberDto> offAutoRenew(String userCode) {
        //查询会员信息
        MemberEntity memberEntity = memberDao.getMembers(userCode, new Date());
        if (memberEntity == null) {
            return Response.error(TradeResultStatus.NO_MEMBER);
        }
        memberEntity.setAutoRenew(TradeType.OFF_AUTO_RENEW.getType());
        memberDao.updateByPrimaryKey(memberEntity);
        return Response.ok(mapper.toDto(memberEntity));
    }

    /**
     * 判断用户是否是会员
     * @param userCode
     * @return
     */
    @Override
    public Response<Boolean> ifMember(String userCode) {
        Map<String, Object> map = new HashMap<>();
        map.put("userCode", userCode);
        map.put("deleted", 0);
        map.put("date", new Date());
        Integer result = memberDao.ifMember(map);
        return Response.ok(result > 0);
    }

    /**
     * 是否有过会员记录
     * @param userCode
     * @return
     */
    @Override
    public Response<Boolean> haveMemberRecord(String userCode) {
        Map<String, Object> map = new HashMap<>();
        map.put("userCode", userCode);
        map.put("deleted", 0);
        Integer result = memberDao.ifMember(map);
        return Response.ok(result > 0);
    }

    /**
     * 获取自动订阅开关
     */
    public static TradeType getTradeType(Integer purchaseType) {
        if (Objects.nonNull(purchaseType) && purchaseType.equals(PurchaseType.ONCE_PRODUCT.getType())) {
            return TradeType.OFF_AUTO_RENEW;
        }
        return TradeType.TURN_ON_AUTO_RENEW;
    }

    /**
     * 添加或者更新会员信息
     *
     * @param userCode       用户码
     * @param product 产品信息
     * @return
     */
    @Override
    public Response<MemberDto> saveOrUpdateMember(String userCode, ProductDto product) {

        List<MemberEntity> memberEntities = memberDao.selectMembers(userCode);
        Date date = new Date();
        MemberEntity member;
        //如果此用户不存在会员则新增会员信息
        if (memberEntities != null && !memberEntities.isEmpty()) {
            //如果存在则查询会员是否过期，未过期则更新会员过期时间。过期则设置生效时间为当前日期，过期时间为当前日期+会员天数
            member = memberEntities.get(0);
            if (DateUtil.compare(member.getExpiryDate(), date) < 0) {
                member.setEffectiveDate(date);
                member.setExpiryDate(DateUtil.offsetDay(date, product.getUsageDays()));
            } else {
                member.setExpiryDate(DateUtil.offsetDay(member.getExpiryDate(), product.getUsageDays()));
            }
            member.setAutoRenew(getTradeType(product.getPurchaseType()).getType());
            member.setProductCode(product.getProductCode());
            memberDao.updateByPrimaryKey(member);
        } else {
            member = new MemberEntity();
            member.setUserCode(userCode);
            member.setEffectiveDate(date);
            member.setExpiryDate(DateUtil.offsetDay(date, product.getUsageDays()));
            Snowflake snowflake = IdUtil.createSnowflake(1, 1);
            long id = snowflake.nextId();
            member.setMemberCode(String.valueOf(id));
            member.setMemberType(TradeType.VIP.getType());
            member.setStatus(TradeStatus.ACTIVE.getStatus());
            member.setAutoRenew(getTradeType(product.getPurchaseType()).getType());
            member.setProductCode(product.getProductCode());
            memberDao.insert(member);
        }


        final PushMsgEvent pushEvent = PushMsgEvent.builder().app(AppEnum.MECHAT).fromUserCode(member.getUserCode()).pushBizCodeEnum(PushBizCodeEnum.M20004).build();
        try {
            log.info("PushMsgInfo:{}", JSONObject.toJSONString(pushEvent));
            pushMsgService.pushMsg(pushEvent);
        } catch (Exception e) {
            log.error("PushMsgError:{}", JSONObject.toJSONString(pushEvent), e);
        }

        return Response.ok(mapper.toDto(member));
    }


}
